LT_R_DECREMENT = 0;
LT_R_INCREMENT = 1;

LT_R_LL		= 0;	// my name, :)
LT_R_MID	= 1;
LT_R_UL		= 2;


// Test Case Specification class
Html5Test.TestCase = function(conf) {
	this.name = conf.name;
	this.frameFunc = conf.frameFunc;
	if (this.name === undefined || this.name === null || this.frameFunc === undefined || this.frameFunc === null) return false;
}

// Load Test Manager Module
Html5Test.LoadTestManager = {
	// static-info on testManager
	sFpsUpdateFrequency:	10,	// by default
	sContinuous:	false,

	// static-info on current test-case
	sCurrentTestCase:	null,
	sCurrentTestCaseId:	0,
	sRunningTime:		0,
	sTestCaseTimeStart:	0,
	sInterval:	null,

	// runtime-info while running test-case
	rRenderTimeStart:	0,
	rRenderTimeStop:	0,
	rRenderTimeSum: 	0,
	rRenderTimeAverage:	0,
	rRenderCount:		0,
	rRenderFps:			0,

	// load adjustment
	rLoad:				1000,
	/*rLoadMid:			15,
	rLoadLowerLim:		10,
	rLoadUpperLim:		20,
	rPreviousState:		LT_R_MID,
	rScaleTimeCycle:	0, */
	
	caseList: [],

	addCase: function(_case) {
		this.caseList.push(_case);
	},

	initializeTags: function(tagArea) {
		var testCase, element;
		for (var i = 0; i < this.caseList.length; i++) {
			testCase = this.caseList[i];
			element = document.createElement("div");
			element.className = "tag";
			element.id = testCase.name;
			element.innerHTML = testCase.name;
			tagArea.appendChild(element);
			element.onclick = function(x, name) {
				return function() {
					Html5Test.LoadTestManager.sCurrentTestCaseId = x;
					$(".tag").removeClass("chosen");
					$("#"+name).addClass("chosen");
				}
			}(i, testCase.name);
		}
		if (this.caseList.length > 0) {
			this.sCurrentTestCase = this.caseList[this.sCurrentTestCaseId];
		}
	},

	singleTest: function() {
		if (this.initCurrentTestCase())
		{
			this.startCurrentTestCase();
		} else {
			alert("Unavaliable currentTestCaseId");
		}
	},
	
	cascadeTest: function() {
		alert("NOT FINISHED YET");
		//this.clearUp();
		//this.initCurrentTestCase();
		//this.startCurrentTestCase();
	},

	hasNextTestCase: function() {
		return (this.sCurrentTestCaseId < this.caseList.length);
	},

	initCurrentTestCase: function() {
		if (!this.hasNextTestCase()) return false;
		this.sCurrentTestCase = this.caseList[this.sCurrentTestCaseId];
		this.sCurrentTestCase.init({
			ctx: 	Html5Test._core.ctx,
			width: 	Html5Test._core.canvas.width,
			height:	Html5Test._core.canvas.height
		});
		this.rRenderCount = 0;
		this.rRenderFps = 0;

		this.rRenderTimeStart = 0;
		this.rRenderTimeStop = 0;

		this.rRenderTimeSum = 0;
		this.rRenderTimeAverage = 0;
		return true;
	},

	startCurrentTestCase: function() {
		this.sTestCaseTimeStart = new Date().valueOf();
		this.sInterval = setInterval(LoadTestCase, Html5Test._core.cycle);
	},
	
	/*pause: function() {
		clearInterval(this.sInterval);
	},

	resume: function() {
		this.sInterval = setInterval(LoadTestCase, Html5Test._core.cycle);
	}, */

	clearUp: function() {
		if (this.sCurrentTestCase && this.sCurrentTestCase.release) {
			this.sCurrentTestCase.release();
		}
	},

	beforeRender: function() {
		this.rRenderTimeStart = new Date().valueOf();					
	},

	afterRender: function() {
		this.rRenderTimeStop = new Date().valueOf();
		this.sRunningTime = Math.floor((this.rRenderTimeStop - this.sTestCaseTimeStart) / 1000);
		var delta = this.rRenderTimeStop - this.rRenderTimeStart;
		this.rRenderTimeSum += delta;
		++this.rRenderCount;
		
		if ((this.rRenderTimeSum > Html5Test._core.cycle * this.sFpsUpdateFrequency) || 
				(this.rRenderCount == this.sFpsUpdateFrequency)) {
			this.updateFpsAndLoad();
		}
	},

	render: function() {
		this.sCurrentTestCase.frameFunc(this.rLoad);
	},

	/*
	**	version 1.0
	**	linear approximate
	*/
	/*adjustLoadIncrement: function() {
		var newLoad = Math.floor(this.rLoad * Html5Test._core.cycle / this.rRenderTimeAverage);
		this.rLoad = newLoad / this.rLoad < 2 ? newLoad : this.rLoad * 2;
	},
	
	adjustLoadDecrement: function() {
		var newLoad = Math.floor(this.rLoad * Html5Test._core.cycle / this.rRenderTimeAverage);
		this.rLoad = this.rLoad / newLoad < 2 ? newLoad : this.rLoad >>> 1;
		this.rLoad = this.rLoad > 1 ? this.rLoad : 1;
	},
	*/
	
	/*
	**	version 2.0
	**	optimized binary approximate
	*/
	adjustLoadIncrement: function() {
		this.rLoad += 100;
		/*
		if (this.rPreviousState == LT_R_MID) {
			this.rLoad = Math.floor(this.rLoadUpperLim);
			this.rLoadLowerLim = this.rLoadMid;
			this.rLoadMid = (this.rLoadLowerLim + this.rLoadUpperLim) / 2;
			this.rPreviousState = LT_R_UL;
		} else if (this.rPreviousState == LT_R_LL) {
			this.rLoad = Math.floor(this.rLoadMid);
			this.rPreviousState = LT_R_MID;
		} else if (this.rPreviousState == LT_R_UL) {
			this.rScaleTimeCycle = Html5Test._core.cycle / this.rRenderTimeAverage;
			this.rLoadLowerLim = this.rLoadUpperLim;
			this.rLoadUpperLim = this.rLoadUpperLim * 2;
			this.rLoadMid = (this.rLoadUpperLim + this.rLoadLowerLim) / 2;
			this.rLoad = Math.floor(this.rLoadMid);
			this.rPreviousState = LT_R_MID;
		}*/
	},
	
	adjustLoadDecrement: function() {
		this.rLoad -= 100;
/*
		if (this.rPreviousState == LT_R_MID) {
			this.rLoad = Math.floor(this.rLoadLowerLim);
			this.rLoadUpperLim = this.rLoadMid;
			this.rLoadMid = (this.rLoadLowerLim + this.rLoadUpperLim) / 2;
			this.rPreviousState = LT_R_LL;
		} else if (this.rPreviousState == LT_R_LL) {
			this.rScaleTimeCycle = Html5Test._core.cycle / this.rRenderTimeAverage;
			this.rLoadUpperLim = this.rLoadLowerLim;
			this.rLoadLowerLim = this.rLoadLowerLim * 0.5;
			if (this.rLoadLowerLim < 1) {
				this.rLoadLowerLim = 1;
			}
			this.rLoadMid = (this.rLoadUpperLim + this.rLoadLowerLim) / 2;
			this.rLoad = Math.floor(this.rLoadMid);
			this.rPreviousState = LT_R_MID;
		} else if (this.rPreviousState == LT_R_UL) {
			this.rLoad = Math.floor(this.rLoadMid);
			this.rPreviousState = LT_R_MID;
		}*/
	},
	
	stabilizeLoadIncrement: function() {
		if (this.rPreviousState = LT_R_MID) {
			return;
		} else if (this.rPreviousState = LT_R_LL) {
			this.rLoadUpperLim = this.rLoadMid;
			this.rLoadMid = this.rLoadLowerLim;
			this.rLoadLowerLim = 2 * this.rLoadMid - this.rLoadUpperLim;
			this.rPreviousState = LT_R_MID;
		} else if (this.rPreviousState = LT_R_UL) {
			this.rLoadLowerLim = this.rLoadMid;
			this.rLoadMid = this.rLoadUpperLim;
			this.rLoadUpperLim = 2 * this.rLoadMid - this.rLoadLowerLim;
			this.rPreviousState = LT_R_MID;
		}
	},
	
	// update rRenderTimeAverage & rRenderFps
	updateFpsAndLoad: function() {
		this.rRenderTimeAverage = this.rRenderTimeSum / this.rRenderCount;
		this.rRenderFps = 1000 / this.rRenderTimeAverage;
		this.rRenderCount = 0;
		this.rRenderTimeSum = 0;
				
		// trigger the condition for adjust Load
		if (this.rRenderTimeAverage > Html5Test._core.cycle) {
			this.adjustLoadDecrement();
		} else if (this.rRenderTimeAverage < Html5Test._core.cycle) {
			this.adjustLoadIncrement();
		} /*else {
			this.stabilizeLoadIncrement();
		}*/
	}
}

function LoadTestCase() {
	Html5Test.LoadTestManager.beforeRender();
	Html5Test.LoadTestManager.render();
	Html5Test.LoadTestManager.afterRender();
	Html5Test.Observer.update();
}
